package com.example.springboot.utils.file;

import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

public class FileUtil {

    private FileUtil() {
    }

    /**
     * TODO 删除一个文件或者一个文件夹下的所有文件(删除后无法恢复!!!)
     */
    public static void clearAndDelete(String path) {
        File file = new File(path);
        if (file.exists()) {
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                for (File tempFile : files) {
                    if (tempFile.isDirectory()) {
                        clearAndDelete(tempFile.getAbsolutePath());
                    }
                    tempFile.delete();
                }
            }
            file.delete();
        }
    }

    /**
     * TODO 仅删除该目录下的文件,不删除文件夹
     */
    public static void deleteFileInForlder(String filePath) {
        File file = new File(filePath);
        File[] files = file.listFiles();
        for (File tempFile : files) {
            if (tempFile.isFile()) {
                tempFile.delete();
            }
        }
    }


    @SuppressWarnings("deprecation")
    public static String transferToImage(String stream, HttpServletRequest request, String fileNo) throws Exception {
        String basePath = request.getRealPath(File.separator);
        String relativePath = "upload/picture/" + System.currentTimeMillis() + "_" + fileNo + ".jpg";
        String imgFilePath = basePath + relativePath;// "D:\\testdata\\222.jpg";//新生成的图片
        File file = new File(basePath + "upload/picture/");
        // 如果文件夹不存在则创建
        if (!file.exists() && !file.isDirectory()) {
            file.mkdir();
        } else {
            clearAndDelete(basePath + "upload/picture/");
        }
        boolean t = stream.matches("^[A-Za-z0-9]+$");
        try {
            if (!t) {
                generateImageByBASE64(stream, imgFilePath);
            } else {
                generateImage(stream, imgFilePath);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return relativePath;
    }

    public static void generateImage(String stream, String imgFilePath) throws Exception {
        OutputStream out = new FileOutputStream(imgFilePath);
        byte[] fileStream = hex2byte(stream);
        InputStream in = new ByteArrayInputStream(fileStream);
        try {
            byte[] b = new byte[1024];
            int nRead = 0;
            while ((nRead = in.read(b)) != -1) {
                out.write(b, 0, nRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            in.close();
            out.close();
        }
    }

    public static void generateImageByBASE64(String stream, String imgFilePath) throws Exception {
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] b = decoder.decodeBuffer(stream);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 调整异常数据
                    b[i] += 256;
                }
            }
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static byte[] hex2byte(String str) { // 字符串转二进制
        if (str == null) {
            return null;
        }
        str = str.trim();
        int len = str.length();
        if (len == 0 || len % 2 == 1) {
            return null;
        }
        byte[] b = new byte[len / 2];
        try {
            for (int i = 0; i < str.length(); i += 2) {
                b[i / 2] = (byte) Integer.decode("0X" + str.substring(i, i + 2)).intValue();
            }
            return b;
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * TODO 文件下载
     *
     * @param byts     二进制流文件
     * @param fileName 包含文件后缀名即包含类型
     */
    public static void writeToResponse(HttpServletRequest request, HttpServletResponse response, byte[] byts, String fileName) {
        // 清空response
        response.reset();
        // 设置response的Header
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        response.addHeader("Content-Length", "" + byts.length);
        response.setContentType("Application/octet-stream;charset=utf-8");
        try {
            OutputStream outputStream = response.getOutputStream();
            outputStream.write(byts);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成导出文件名称
     *
     * @param fileName
     */
    public static String getExportFileName(String fileName) {
        // 设置要导出的文件名称
        StringBuilder sub = new StringBuilder();
        sub.append(fileName).append("-");
        SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = datetimeFormat.format(new Date());
        sub.append(date);
        String str = sub.toString();
        return str;
    }

    /**
     * @return String 返回类型
     * @Description:将文件保存到指定位置
     */
    public static void writeFile(InputStream input, OutputStream output) throws IOException {
        IOUtils.copy(input, output);
        IOUtils.closeQuietly(output);
        IOUtils.closeQuietly(input);
    }

    /**
     * @return String 返回类型
     * @Description:将文件保存到指定位置
     */
    public static void writeFile(Reader input, Writer output) throws IOException {
        IOUtils.copy(input, output);
        IOUtils.closeQuietly(output);
        IOUtils.closeQuietly(input);
    }

    /**
     * 获取文件类型
     *
     * @param fileName
     * @return
     */
    public static String getContentType(String fileName) {
        if (fileName.indexOf(".docx") > -1) {
            return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        } else if (fileName.indexOf(".doc") > -1) {
            return "application/msword";
        } else if (fileName.indexOf(".pdf") > -1) {
            return "application/pdf";
        } else if (fileName.indexOf(".xlsx") > -1) {
            return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        } else if (fileName.indexOf(".xls") > -1) {
            return "application/vnd.ms-excel";
        } else if (fileName.indexOf(".pptx") > -1 || fileName.indexOf(".pptm") > -1) {
            return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
        } else if (fileName.indexOf(".ppt") > -1) {
            return "application/vnd.ms-powerpoint";
        } else if (fileName.indexOf(".jpg") > -1) {
            return "application/x-jpg";
        } else if (fileName.indexOf(".gif") > -1) {
            return "image/gif";
        } else if (fileName.indexOf(".png") > -1) {
            return "application/x-png";
        }
        return null;
    }


    /**
     * @param fileName：带路径的文件
     * @return:真实文件名
     */
    public static String getFileRealName(String fileName) {
        // 真实文件名
        String realName = fileName.substring(fileName.lastIndexOf(File.separator) + 1, fileName.length());
        return realName;
    }

    /**
     * @param fileName：文件名
     * @return:文件后缀
     */
    public static String getFileSubfix(String fileName) {
        // 真实文件名
        String fileSubfix = fileName.substring(fileName.lastIndexOf("."), fileName.length());
        return fileSubfix;
    }

    /**
     * 下载文件
     */
    public static void donwload(String localPath, byte[] buf, String fileName) throws Exception {
        if (buf != null && !"".equals(buf)) {
            OutputStream out = new FileOutputStream(new File(localPath + "/" + fileName));
            out.write(buf, 0, buf.length);
            out.flush();
            out.close();
        }
    }

    /**
     * 下载文件并返回http访问链接
     */
    public static String download(HttpServletRequest request, byte[] buf, String fileName, String filePath) {
        String path = "";
        try {
            /* 下载图片至本地  */
            // 项目真实路径
            String file = request.getSession().getServletContext().getRealPath(File.separator);

            // 下载图片
            FileUtil.donwload(file + filePath, buf, fileName);
            // 项目路径
            String projectName = request.getContextPath();
            // http访问路径
            path = projectName + filePath + fileName;
            /* 下载图片至本地  */
        } catch (Exception e) {
            e.printStackTrace();
        }
        return path;
    }


    private static Properties prop = new Properties();

    public static Properties loadFiles(String... filePaths) {
        for (int i = 0, j = filePaths.length; i < j; i++) {
            InputStream input = null;
            try {
                input = FileUtil.class.getClassLoader().getResourceAsStream(filePaths[i]);
                prop.load(input);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (input != null) {
                    try {
                        input.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return prop;
    }


    private static Map<String, String> map = new HashMap<String, String>();

    /**
     * 加载指定的properties配置文件到全局的map对象中
     *
     * @param filePath
     */
    private static Map<String, String> loadFile(String filePath) {
        // 判断map是否为空
        if (null == map) {
            // 当map为空时初始化map对象
            map = new HashMap<String, String>();
        }
        if (null == filePath || "".equals(filePath.trim())) {
            System.out.println("The file path is null,return");
            return null;
        }
        filePath = filePath.trim();
        // 获取资源文件
        InputStream is = FileUtil.class.getClassLoader().getResourceAsStream(filePath);
        // 属性列表
        Properties prop = new Properties();
        try {
            // 从输入流中读取属性列表
            prop.load(is);
            // 返回Properties中包含的key-value的Set视图
            Set<Map.Entry<Object, Object>> set = prop.entrySet();
            // 返回在此Set中的元素上进行迭代的迭代器
            Iterator<Map.Entry<Object, Object>> it = set.iterator();
            // 循环取出key-value
            while (it.hasNext()) {
                Map.Entry<Object, Object> entry = it.next();
                // 获取properties的key
                String key = entry.getKey().toString();
                // 获取properties的value
                String value = entry.getValue() == null ? "" : entry.getValue().toString();
                // 把遍历的properties的数据添加到map对象中
                map.put(key, value);
            }
        } catch (IOException e) {
            System.out.println("load file faile." + e);
        }
        return map;
    }

    /**
     * 根据传递的key获取map中的值
     *
     * @param key 文件中的key
     * @return key对应的结果
     */
    public static String getValue(String key) {
        if (null == map) {
            System.out.println("map is null!");
            return null;
        }
        return map.get(key);
    }

    public static void main(String[] args) {

        String value = getValue("timeCount");
        System.out.println(value);


        Properties pro = loadFiles("data-sync.properties");
        String val = pro.getProperty(null);
        System.out.println(val);

        String fileName = "\\app\\file.txt";
        String realName = fileName.substring(fileName.lastIndexOf(File.separator) + 1, fileName.length());
        System.out.println(realName);
    }
}
